package com.snake;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class GamePanel extends JPanel {
    private volatile int[] snakeX = new int[200];
    private volatile int[] snakeY = new int[200];
    private volatile int length;
    private volatile String direction = "R";
    private volatile int foodX, foodY;
    private volatile int score;
    private volatile boolean isStart = false;
    private volatile boolean isDie = false;
    
    private Thread gameThread;
    private volatile boolean running = false;
    private final Lock lock = new ReentrantLock();
    
    private final Color SNAKE_COLOR = new Color(46, 125, 50);
    private final Color APPLE_COLOR = new Color(244, 67, 54);
    private final Color APPLE_STEM_COLOR = new Color(101, 67, 33);
    private final Color APPLE_LEAF_COLOR = new Color(76, 175, 80);
    
    private JDialog gameOverDialog;

    public GamePanel() {
        initSnake();
        createFood();
        
        setFocusable(true);
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                
                // 处理方向键（仅在游戏未结束且已开始时）
                if (!isDie && isStart) {
                    handleDirectionKeys(keyCode);
                }
                
                // 空格键处理
                if (keyCode == KeyEvent.VK_SPACE) {
                    if (isDie) {
                        // 只显示结束窗口，不重置游戏
                        if (gameOverDialog == null || !gameOverDialog.isVisible()) {
                            showGameOverWindow();
                        }
                    } else {
                        isStart = !isStart;
                        repaint();
                    }
                }
            }
        });
        
        startGameThread();
    }
    
    private void handleDirectionKeys(int keyCode) {
        lock.lock();
        try {
            switch (keyCode) {
                case KeyEvent.VK_UP:
                    if (!"D".equals(direction)) direction = "U";
                    break;
                case KeyEvent.VK_DOWN:
                    if (!"U".equals(direction)) direction = "D";
                    break;
                case KeyEvent.VK_LEFT:
                    if (!"R".equals(direction)) direction = "L";
                    break;
                case KeyEvent.VK_RIGHT:
                    if (!"L".equals(direction)) direction = "R";
                    break;
            }
        } finally {
            lock.unlock();
        }
    }
    
    private void startGameThread() {
        gameThread = new Thread(() -> {
            running = true;
            while (running) {
                if (isStart && !isDie) {
                    try {
                        lock.lock();
                        updateGame();
                    } finally {
                        lock.unlock();
                    }
                }
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                repaint();
            }
        });
        gameThread.start();
    }
    
    private void updateGame() {
        moveSnake();
        checkFood();
        checkDie();
    }
    
    private void initSnake() {
        length = 3;
        snakeX[0] = 175; snakeY[0] = 275;
        snakeX[1] = 150; snakeY[1] = 275;
        snakeX[2] = 125; snakeY[2] = 275;
        direction = "R";
    }
    
    private void createFood() {
        foodX = (new Random().nextInt(30) + 1) * 25;
        foodY = (new Random().nextInt(26) + 4) * 25;
    }
    
    private void moveSnake() {
        for (int i = length - 1; i > 0; i--) {
            snakeX[i] = snakeX[i - 1];
            snakeY[i] = snakeY[i - 1];
        }
        
        switch (direction) {
            case "U": snakeY[0] -= 25; break;
            case "D": snakeY[0] += 25; break;
            case "L": snakeX[0] -= 25; break;
            case "R": snakeX[0] += 25; break;
        }
    }
    
    private void checkFood() {
        if (snakeX[0] == foodX && snakeY[0] == foodY) {
            length++;
            score += 10;
            createFood();
        }
    }
    
    private void checkDie() {
        if (snakeX[0] < 25 || snakeX[0] > 750 || 
            snakeY[0] < 100 || snakeY[0] > 725) {
            isDie = true;
        }
        
        for (int i = 1; i < length; i++) {
            if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                isDie = true;
                break;
            }
        }
    }
    
    private void showGameOverWindow() {
        SwingUtilities.invokeLater(() -> {
            if (gameOverDialog != null && gameOverDialog.isVisible()) {
                return;
            }
            
            gameOverDialog = new JDialog();
            gameOverDialog.setTitle("游戏结束");
            gameOverDialog.setSize(400, 300);
            gameOverDialog.setLocationRelativeTo(null);
            gameOverDialog.setModal(true);
            gameOverDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
            gameOverDialog.setLayout(new BorderLayout());
            
            JPanel scorePanel = new JPanel(new GridBagLayout());
            scorePanel.setBackground(new Color(240, 240, 240));
            
            JLabel titleLabel = new JLabel("最终得分:");
            titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 28));
            
            JLabel scoreLabel = new JLabel(String.valueOf(score));
            scoreLabel.setFont(new Font("微软雅黑", Font.BOLD, 56));
            scoreLabel.setForeground(score > 60 ? Color.GREEN : Color.RED);
            
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(20, 0, 30, 0);
            gbc.gridx = 0;
            gbc.gridy = 0;
            scorePanel.add(titleLabel, gbc);
            
            gbc.gridy = 1;
            scorePanel.add(scoreLabel, gbc);
            
            JButton restartButton = new JButton("重新开始");
            restartButton.setFont(new Font("微软雅黑", Font.PLAIN, 20));
            restartButton.addActionListener(e -> {
                initSnake();
                createFood();
                isDie = false;
                isStart = false; // 重置后游戏处于暂停状态
                score = 0;
                gameOverDialog.dispose();
                repaint();
            });
            
            JPanel buttonPanel = new JPanel();
            buttonPanel.add(restartButton);
            
            gameOverDialog.add(scorePanel, BorderLayout.CENTER);
            gameOverDialog.add(buttonPanel, BorderLayout.SOUTH);
            gameOverDialog.setVisible(true);
        });
    }
    
    private void drawApple(Graphics g, int x, int y) {
        // 苹果主体
        g.setColor(APPLE_COLOR);
        g.fillOval(x, y, 25, 25);
        
        // 高光效果
        g.setColor(new Color(255, 255, 255, 150));
        g.fillOval(x + 5, y + 5, 8, 8);
        
        // 苹果柄
        g.setColor(APPLE_STEM_COLOR);
        g.drawLine(x + 12, y - 3, x + 12, y + 2);
        
        // 苹果叶
        g.setColor(APPLE_LEAF_COLOR);
        g.fillArc(x + 8, y - 8, 10, 10, 0, 180);
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        // 双缓冲
        Image buffer = createImage(getWidth(), getHeight());
        Graphics bufferGraphics = buffer.getGraphics();
        drawGame(bufferGraphics);
        g.drawImage(buffer, 0, 0, this);
    }
    
    private void drawGame(Graphics g) {
        // 背景
        g.setColor(new Color(208, 220, 226));
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(new Color(219, 226, 219));
        g.fillRect(10, 70, 770, 685);
        
        // 绘制蛇
        drawSnake(g);
        
        // 绘制苹果
        drawApple(g, foodX, foodY);
        
        // 分数
        g.setColor(Color.BLACK);
        g.setFont(new Font("微软雅黑", Font.BOLD, 20));
        g.drawString("分数: " + score, 650, 40);
        
        // 游戏状态
        drawGameStatus(g);
    }
    
    private void drawSnake(Graphics g) {
        lock.lock();
        try {
            // 蛇头
            g.setColor(SNAKE_COLOR);
            g.fillRect(snakeX[0], snakeY[0], 25, 25);
            
            // 眼睛
            g.setColor(Color.WHITE);
            switch (direction) {
                case "U": 
                    g.fillOval(snakeX[0]+5, snakeY[0]+5, 5, 5);
                    g.fillOval(snakeX[0]+15, snakeY[0]+5, 5, 5);
                    break;
                case "D":
                    g.fillOval(snakeX[0]+5, snakeY[0]+15, 5, 5);
                    g.fillOval(snakeX[0]+15, snakeY[0]+15, 5, 5);
                    break;
                case "L":
                    g.fillOval(snakeX[0]+5, snakeY[0]+5, 5, 5);
                    g.fillOval(snakeX[0]+5, snakeY[0]+15, 5, 5);
                    break;
                case "R":
                    g.fillOval(snakeX[0]+15, snakeY[0]+5, 5, 5);
                    g.fillOval(snakeX[0]+15, snakeY[0]+15, 5, 5);
                    break;
            }
            
            // 蛇身
            for (int i = 1; i < length; i++) {
                g.setColor(SNAKE_COLOR);
                g.fillRoundRect(snakeX[i], snakeY[i], 25, 25, 10, 10);
            }
        } finally {
            lock.unlock();
        }
    }
    
    private void drawGameStatus(Graphics g) {
        if (!isStart && !isDie) {
            g.setColor(new Color(114, 98, 255));
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("按空格键开始游戏", 250, 330);
        }
        
        if (isDie) {
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑", Font.BOLD, 20));
            g.drawString("游戏结束，按空格键查看结果", 200, 330);
        }
    }
    
    public void stopGame() {
        running = false;
        if (gameThread != null) {
            gameThread.interrupt();
        }
    }
}